//
//  Rx+withLatestFrom.swift
//  SwiftCode
//
//  Created by yuhus on 2023/10/30.
//

import RxSwift

/// 将两个 Observables 最新的元素通过一个函数组合起来，当第一个 Observable 发出一个元素，就将组合后的元素发送出来
func withLatestFromRx() {
//  test1()
  test2()
}

private func test1() {
  let first = PublishSubject<String>()
  let second = PublishSubject<Int>()
  
  first.onNext("A")
  second.onNext(1)
  
  first.onNext("B")
  second.onNext(2)
  
  _ = first
    .debug()
    .withLatestFrom(second.debug()) {
      "\($0 ) + \($1)"
    }
    .subscribe {
      Timber.d($0)
    }
  
  first.onNext("C")
  //  second.onNext(3)
  
  delay(seconds: 1) {
    first.onNext("D")
    second.onNext(4)
  }
}

private func test2() {
  let first = PublishSubject<String>()
  let second = BehaviorSubject<Int>(value: -1)
  
  first.onNext("A")
  second.onNext(1)
  
  first.onNext("B")
  second.onNext(2)
  
  _ = first
    .debug()
    .withLatestFrom(second.debug()) {
      "\($0 ) + \($1)"
    }
    .subscribe {
      Timber.d($0)
    }
  // (C + 2); (D + 3)
  
  first.onNext("C")
    second.onNext(3)
  
  delay(seconds: 1) {
    first.onNext("D")
    second.onNext(4)
  }
}

private func delay(seconds: Int, closure: @escaping ()->()) {
  let time = DispatchTime.now() + .seconds(seconds)
  DispatchQueue.main.asyncAfter(deadline: time) {
    print("🕑")
    closure()
  }
}
